#pragma once

#include "../../../include/net_interface.hpp"
#include "../../../include/objpool.hpp"
#include "P2PSession.h"
#include <map>

class CSvrPacketParser :
    public IPacketParser
{
public:
    virtual INT32 ParsePacket(const char* pData, const INT32 iLen);
};

struct PeerInfo 
{
    UINT32 p2p_id;
    UINT16 nat_type;
    UINT32 public_ip;
    UINT16 public_port;
    UINT32 private_ip;
    UINT16 private_port;
    UINT16 stat;
};

typedef std::map<UINT32, PeerInfo*>     TPeerInfoMap;
typedef TPeerInfoMap::iterator          TPeerInfoIter;

class CP2P;

typedef std::map<UINT32, CP2PSession*>  TP2PSessionMap;
typedef TP2PSessionMap::iterator        TP2PSsessionIter;

class CP2PSessionManager :
    public ISessionManager
{
public:
    CP2PSessionManager(CP2P* p2p);
    virtual ~CP2PSessionManager(void);

    virtual void OnEstablish(HNETHANDLE hHandle, HSESSION hSession);
    virtual void OnTerminate(HSESSION hSession);
    virtual void OnError(HNETHANDLE hHandle, HSESSION hSession, INT32 iModuleError, INT32 iSystemError);
    virtual void OnRecv(HSESSION hSession, const char* pData, const INT32 iLen);

    bool AddP2PSession(CP2PSession& p2p_session);
    CP2PSession* FindP2PSession(UINT32 p2p_id);
    void DelP2PSession(UINT32 p2p_id);

    bool AddPeerInfo(PeerInfo& peer_info);
    PeerInfo* FindPeerInfo(UINT32 p2p_id);
    void DelPeerInfo(UINT32 p2p_id);

    DEFREFMEMBER(CObjPool<CP2PSession>, m_p2p_session_pool, p2p_session_pool)
    DEFREFMEMBER(CObjPool<CNATTestSession>, m_nat_test_session_pool, nat_test_session_pool)
    DEFREFMEMBER(CObjPool<PeerInfo>, m_peer_info_pool, peer_info_pool)
    DEFREFMEMBER(CObjPool<CPunchSession>, m_punch_session_pool, punch_session_pool)
protected:
    CP2P*   m_p2p;
    TP2PSessionMap      m_p2p_session_map;
    TPeerInfoMap        m_peer_info_map;
};
